<?php
/**
 * 统计留存率 的php脚本
 * windows下 》管理工具 》任务计划程序 》每天03:00执行一次
 * 将结果写入mysql 的 表中
 *
 *
 * 查询注册的表 当天注册的会员信息
 * 前一天的登录信息
 * 留存率 = 新增用户中登录用户数/新增用户数 * 100%   （一般统计周期为天）
 *
 * 新增用户数：在某个时间段（一般为第一整天）新登录应用的用户数；
 * 登录用户数：登录应用后至当前时间，至少登录过一次的用户数；
 */

//执行统计
$go = new retention;
////统计2日留存
////$today = Date('Y-m-d',time());
////$daybefer = Date('Y-m-d',time()-60*60*24);
//$today = "2018-02-11";
//$day2 = "2018-02-09";
//$result = $go->stayTweDay($today,$day2);
//var_dump($result);

////统计3日留存
//$today = "2018-02-13";
//$day2 = "2018-02-12";
//$day3 = "2018-02-11";
//$loginUser3 = $go->stayThreeDay($today,$day2,$day3);
//var_dump($loginUser3);

//统计4日留存率
$today = "2018-02-13";
$loginUser4 = $go->stayFourDay($today);
var_dump($loginUser4);




class retention{
    //var $today;

    /* 次日留存率：（当天新增的用户中，在注册的第2天还登录的用户数）/第一天新增总用户数；
     * 昨天的注册数据 $reg
     * 今天的登录数据 $login
     */
    public function stayTweDay($today,$day2){
        $loginUser=$this->oneDayLogin($today);
        $result['login'] = $loginUser;
        $regUser=$this->oneDayLogin($day2);
        $result['reg'] = $regUser;
        //对比数据
        $tweDayLogin = $this->TwoDayLoginCount($result['reg'],$result['login']);
        $retentionTwo = sprintf("%.2f", count($tweDayLogin) / count($result['login'])*100 );   //次日留存率
        return $retentionTwo  ;
    }


    /*
     * 第3日留存率：（新注册用户，在注册的第3天还有登录的用户数）/3天前注册的总用户数；
     */
    public function stayThreeDay($today,$dayDefer2,$dayDefer3){
        //var_dump($today);
        $result['today'] = $this->oneDayLogin($today);
        $result['dayDefer2'] = $this->oneDayLogin($dayDefer2);
        $result['dayDefer3'] = $this->oneDayLogin($dayDefer3);
        //对比数据
        $LoginDayDefore2 = $this->TwoDayLoginCount($result['dayDefer3'],$result['dayDefer2']);
        $LoginDayDefore3 = $this->TwoDayLoginCount($LoginDayDefore2,$result['today'] );
        //var_dump( $LoginDayDefore3);


        $retentionThree = sprintf("%.2f", count($LoginDayDefore3)/ count($result['dayDefer3'])*100 );   //3日留存率
        //var_dump($retentionTwo);
        return $retentionThree;
    }


    /*
     * 第4日留存率：（新注册用户，在注册的第4天连续登录的用户数）/4天前注册的总用户数；
     */
    public function stayFourDay($today){
        $today   = '2018-02-13';
        $dayDefer2 = '2018-02-12';
        $dayDefer3 = '2018-02-11';
        $dayDefer4 = '2018-02-10';

        $result['today'] = $this->oneDayLogin($today);
        $result['dayDefer2'] = $this->oneDayLogin($dayDefer2);
        $result['dayDefer3'] = $this->oneDayLogin($dayDefer3);
        $result['dayDefer4'] = $this->oneDayLogin($dayDefer4);

        //对比数据
        $LoginDayDefore2 = $this->TwoDayLoginCount($result['dayDefer4'],$result['dayDefer3']); //4天前注册，连续2天登录
        $LoginDayDefore3 = $this->TwoDayLoginCount($LoginDayDefore2,$result['dayDefer2'] );     //4天前注册，连续3天登录
        $LoginDayDefore4 = $this->TwoDayLoginCount($LoginDayDefore3,$result['today'] );          //4天前注册，连续4天登录
        //var_dump( $result['dayDefer4'] );


        $retentionFour = sprintf("%.2f", count($LoginDayDefore4)/ count($result['dayDefer4'])*100 );   //4日留存率
        //var_dump($retentionFour);

        return $retentionFour;
    }


    /*
     * 第7日留存率：（新增的用户中，在注册的第7天还有登录的用户数）/7天前注册的总用户数；
     */

    /*
     * 第30日留存率：（新增的用户中，在注册的第30天还有登录的用户数）/30天前注册的总用户数。
     */


    /*
     * 一天的登录数据
     * 思路： 取得每天的记录 ，php中作对比，windows定时任务 ，每天统计，写入mysql的表中
     */
    public function oneDayLogin($data){
        $data=(string)$data; // '2018-02-09'
        //var_dump($data) ;
        require 'vendor/autoload.php';
        $collection = (new \MongoDB\Client("mongodb://192.168.1.88:27916"))->dbname->loginout;
        $pipe =array(
            array(
                '$project' => array(
                    'time' =>array(
                        '$substr'=>array('$time',0,10)
                    ) ,
                    'gameid'=>'$gameid',
                    'nickname'=>'$nickname',
                ),
            ),
            array(
                '$match'=>array(
                    'time'=>"$data"
                )
            ),
            array(
                '$group' => array(
                    '_id' => '$_id',
                    'gameid'=> array('$addToSet'=>'$gameid'),
                    'nickname'=> array('$push'=>'$nickname'),
                    'time'=> array('$push'=>'$time'),
                ),
            ),
        );
        $cursor =$collection->aggregate($pipe);
        //print_r($cursor);
        $i=0; //指针
        foreach ($cursor as $state) {
            $result[$i]['gameid'] = $state['gameid'][0];
            $result[$i]['nickname'] = $state['nickname'][0];
            $result[$i]['time'] = $state['time'][0];

            //var_dump($result[$i]);
             //echo " -------------------------------------------------------------- ";

            $i++;
        }
        //var_dump($result);
        return $result;
    }

    /*
     * 一天的注册数据
     */
    protected function oneDayReg(){

    }

    /*
     * 对比两天的会员信息
     */
    public function TwoDayLoginCount($day,$beforeDay){
        foreach ($day as $vo){
            if(is_array(reset($day))){
                $day1[]=$vo['gameid'];
            }else{
                $day1[]=$vo;
            }
        }
        foreach ($beforeDay as $value){
            if(!is_array(reset($beforeDay))){
                $day2[]=$value;
            }else{
                $day2[]=$value['gameid'];
            }
        }

        $result = array_intersect($day2,$day1); //交集
        var_dump($result);

        return $result; //返回两天连续登录的人数 交集
    }
}


